/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
const detectCycle = function (head) {
  if (head === null || head.next === null) return null
  let fast = head
  let slow = head
  let start = head
  while (fast !== null && fast.next !== null) {
    fast = fast.next.next
    slow = slow.next

    // 定位环入口
    if (fast === slow) {
      // 当快慢指针相遇时，将慢指针和 start 指针
      // 同速度移动，再次相遇的节点就是环入口
      while (slow !== start) {
        slow = slow.next
        start = start.next
      }
      return start
    }
  }
  return null
}

// another method

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
const detectCycle = head => {
  if (!head) return head
  let currentNode = head
  let previousNode = true
  while (currentNode) {
    if (currentNode.previous) return currentNode
    if (!currentNode.previous) {
      currentNode.previous = previousNode
      previousNode = currentNode
      currentNode = currentNode.next
    }
  }
  return null
}
